home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 245_01 / lca41.c < prev    next >
Text File  |  1987-10-26  |  11KB  |  384 lines

  1.       
  2. /* (4,1) Linear Cellular Automaton    */
  3.  
  4. /* Reference:                */
  5. /*                    */
  6. /*    Kenneth E. Perry            */
  7. /*    Abstract Mathematical Art        */
  8. /*    BYTE                */
  9. /*    December, 1986            */
  10. /*    pages 181-192            */
  11.  
  12. /*    Copyright (C) 1987        */
  13. /*    Harold V. McIntosh        */
  14. /*    Gerardo Cisneros S.        */
  15.  
  16. /* G. Cisneros, 4.3.87                        */
  17. /* 10 April 1987 - modified for (4,2) [HVM]            */
  18. /* 26 April 1987 - Multiple menus [HVM]                */
  19. /* 28 April 1987 - back modified to (4,1) [HVM]            */
  20. /* 28 April 1987 - version for XVI Feria de Puebla [HVM]    */
  21.  
  22. # include <bdos.h>
  23.  
  24. # define COLGRAF     4  /* graph resolution */
  25. # define T80X25      3  /* text resolution */
  26. # define WHCYMAG     1  /* color quad for normal screen */
  27. # define AL        320  /* array length (screen width) */
  28. # define DS        10  /* number of distinct sums */
  29. # define DT        11  /* DS + 1 */
  30. # define NX         51    /* number of sample rules */
  31.  
  32. char xrule[] 
  33.  
  34.     "0001321200"  /* gliders, cycles, changing after 8000 gen */
  35.     "0003120121"  /* fishnet */
  36.     "0020303113"  /* glider from Perry's article */
  37.     "0023003220"  /* barriers and creepers */
  38.     "0003120210"  /* #22 with color runs */
  39.  
  40.     "0010322132"  /* almost a barrier */
  41.     "0012130032"  /* wiggles back and forth */
  42.     "0012130000"  /* no gliders but class iv */
  43.     "0303200131"  /* varicolored cells, blue barriers */
  44.     "0031202003"  /* wiggles */
  45.  
  46.     "0031202023"  /* red and black */
  47.     "0133330222"  /* checkerboard */
  48.     "0331202003"  /* insettled */
  49.     "0101212303"  /* reds fight greens */
  50.     "0120133230"
  51.  
  52.     "0123003220"  /* barrier & irregular creeper */
  53.     "0123022233"  /* green-balck cells */
  54.     "0131123113"  /* gliders */
  55.     "0202311130"  /* marvellous stripes */
  56.     "0203011100"  /* open latticework */
  57.  
  58.     "0203101121"  /* black vs red-blue */
  59.     "0203210031"  /* */
  60.     "0223112303"  /* */
  61.     "0223112313"  /* */
  62.     "0230130120"  /* cycles and wiggles */
  63.  
  64.     "0231123002"  /* almost a bouncing shuttle */
  65.     "0231123003"  /* nice variant */
  66.     "1002120031"  /* mottled */
  67.     "1012333130"  /* uniform */
  68.     "1120311321"  /* pea soup */
  69.  
  70.     "1131301023"  /* threads */
  71.     "1200003011"  /* gliders and walls */
  72.     "1333011002"  /* stripey */
  73.     "2011033320"  /* */
  74.     "3020110010"  /* watch the lattice develop */
  75.  
  76.     "3021331332"  /* oodles of triangles */
  77.     "3100323113"  /* pntd crct bd */
  78.     "3111203022"  /* interesting barriers */
  79.     "3120111330"  /* varicolored cells w/blue barrier */
  80.     "3232221023"  /* interesting barriers */
  81.  
  82.     "3301123211"  /* black stripe */
  83.     "3330121210"  /* varied */
  84.     "3331202110"  /* venetian blind */
  85.     "3332020321"  /* checkered table cloth */
  86.     "3332121001"  /* small cells */
  87.  
  88.     "3332320120"  /* zebra glider */
  89.     "3333120121"  /* another glider */
  90.     "3333120122"  /* two speeds of glider */
  91.     "3333122101"  /* aggressive green & stripes */
  92.     "3333210120"  /* slow gliders */
  93.  
  94.     "3333220113"  /* triangles vs checkers */
  95.  
  96.     ;
  97.  
  98. char  xx[4], rule[DT];
  99. int   arule[DS], arr1[AL], arr2[AL];
  100.  
  101. main()
  102. {
  103. int c, i, jj, n;
  104. int  more = 'r';
  105.  
  106.     videopalette(WHCYMAG);                /* white/cyan/magenta */
  107.  
  108.     tuto();
  109.     while (!kbdst()) jj=rand();                /* wait for keypress */
  110.     c=kbdin();                        /* ignore it */
  111.     jj=rand()%NX;
  112.     for (i=0; i<DS; i++) rule[i] = xrule[DS*jj+i];    /* random sample rule */
  113.     rule[DS]=0;
  114.     for (i=0; i<AL; i++) {                /* random initial array */
  115.     if (i%4 == 0) c=rand();
  116.     arr1[i]=c&3; c>>=2;};
  117.     videomode(T80X25);
  118.     videoscroll(3,0,4,71,0,3);                /* menu on blue background */
  119.     videoscroll(16,0,21,71,0,3);
  120.     xmenu(jj+1);                    /* show initial rule */
  121.  
  122.     while (more!='n') {                    /* execute multiple runs */
  123.     rmenu();
  124.     lmenu();
  125.     while (0<1) {                    /* set up one run */
  126.     c=kbdin();
  127.     if (c=='g') break;                    /* go draw graph */
  128.     if (c=='q') more='n';                /* quit for good */
  129.     if (more=='n') break;
  130.     switch (c) {
  131.         case 'r':                    /* edit rule */    
  132.         xblnk();
  133.         edrule();
  134.         videocursor(0,3,0);
  135.         rmenu();
  136.         break;
  137.         case 'l':                    /* edit cell string */
  138.         xblnk();
  139.         edline();
  140.         videocursor(0,3,0);
  141.         lmenu();
  142.         break;
  143.         case '#':                    /* read stored rule */
  144.         xmenu(NX);
  145.         n=DS*((i=lim(1,numin(0),NX))-1);
  146.         xmenu(i);
  147.         for (i=0; i<DS; i++) rule[i] = xrule[n+i];
  148.         rmenu();
  149.             break;
  150.         case 'u':
  151.         xblnk();
  152.         for (i=0; i<AL; i++) arr1[i]=0;
  153.         arr1[AL/4]=1;
  154.             arr1[AL/2]=2;
  155.             arr1[(3*AL)/4]=3;
  156.         lmenu();
  157.             break;
  158.     case 'x':                    /* random rule */
  159.         xblnk();
  160.             for (i=0; i<DS; i++) {
  161.             if (i%4 == 0) c = rand();
  162.             rule[i] = '0'+(c & 3);
  163.             c >>= 2;
  164.             };
  165.         rmenu();
  166.         break;
  167.     case 'y':                    /* random line */
  168.         xblnk();
  169.         for (i=0; i<AL; i++) {
  170.             if (i%4 == 0) c = rand();
  171.             arr1[i] = c & 3;
  172.             c >>= 2;
  173.             };
  174.             lmenu();
  175.         break;
  176.         default: break;
  177.         };
  178.     };
  179.     if (more=='n') break;
  180.     do {
  181.     evolve(rule);
  182.     videocursor(0,0,0);
  183.     scrstr("More?");
  184.     videocursor(0,0,30);
  185.     scrstr("y/n/cr");
  186.     more=kbdin();
  187.     } while (more=='\015');
  188.     videomode(T80X25);                    /* reset the screen */
  189.     if (more=='n') break;
  190.     };
  191. }    
  192.  
  193. edrule()                        /* edit the rule */
  194. {
  195. char c;
  196. int  i;
  197.  
  198.     videocursor(0,1,6);                    /* get the rule */
  199.     i=0;
  200.     while (i<DS) {
  201.         videoputc(rule[i],2);
  202.         videoputc('\010',1);
  203.         c = kbdin();
  204.         if (c == '\015') break;
  205.         switch (c) {
  206.         case '0':  case '1': case '2': case '3':    /* state */
  207.             rule[i++] = c;
  208.             videoputc(c,1);
  209.             break;
  210.         case ' ':                    /* space = advance */
  211.             videoputc(rule[i++],1);
  212.             break;
  213.         case '\010':                    /* backspace */
  214.             if (i==0) break;
  215.             videoputc(rule[i--],1);
  216.             videoputc(c,1);
  217.             videoputc(c,1);
  218.             break;
  219.     default: break;
  220.         };
  221.     };
  222. }
  223.  
  224. edline() {                        /* edit the line */
  225.  
  226. char c;
  227. int  i, j, k, ii, jj;
  228.  
  229.     videocursor(0,16,0);
  230.     scrstr("insert states using 0, 1, 2, 3");
  231.     videocursor(0,17,0);
  232.     scrstr("move cursor with n(north), s(south), e(east), w(west), or");
  233.     videocursor(0,18,0);
  234.     scrstr("with keyboard arrows. Space, backspace move right and left.");
  235.     videocursor(0,19,0);
  236.     scrstr("( seeks left margin, < absolutely, { up one line, [ down one line");
  237.     videocursor(0,20,0);
  238.     scrstr(") seeks right margin, > absolutely, } up one line, ] down one line");
  239.     videocursor(0,21,0);
  240.     scrstr("carriage return exits");
  241.     jj=4;
  242.     ii=1;
  243.     while (0<1) {
  244.     ii=lim(1,ii,40);
  245.     jj=lim(1,jj,8);
  246.     j=jj-1;
  247.     i=ii-1;
  248.     videocursor(0,j+6,i);
  249.     c=kbdin();
  250.     if (c == '\015') {videoscroll(16,0,21,70,0,3); break;};
  251.     switch (c) {
  252.     case '0':  case '1': case '2': case '3':        /* enter  state */
  253.         arr1[40*j+i] = c-'0';
  254.     ii++;
  255.     break;
  256.     case 's': case '\012': case '\320':          jj++; break;    /* down - next line */
  257.     case 'n': case '\013': case '\310':          jj--; break;    /* up   - last line */
  258.     case 'e': case '\014': case '\315': case ' ': ii++; break;    /* space = advance  */
  259.     case 'w': case '\010': case '\313':          ii--; break;    /* backspace */
  260.     case '<': ii=1;  jj=1;  break;  /* absolute left */
  261.     case '{': ii=1;  jj--;  break;  /* left one row up */
  262.     case '(': ii=1;         break;  /* left this row */
  263.     case '[': ii=1;  jj++;  break;  /* left next row */
  264.     case '>': ii=40; jj=40; break;  /* absolute right */
  265.     case '}': ii=40; jj--;  break;  /* right one row up */
  266.     case ')': ii=40;        break;  /* right this row */
  267.     case ']': ii=40; jj++;  break;  /* right next row */
  268.     default: break;
  269.         };
  270.     videocursor(0,j+6,0);
  271.     for (k=0; k<40; k++) videoputc('0'+arr1[40*j+k],1);
  272.     };
  273. }
  274.  
  275. evolve(rule)                        /* display a screen of evolution */
  276. char *rule;
  277. {
  278. int i, j, sum, sum0, sum1;
  279.  
  280.     videomode(COLGRAF);                    /* erase the screen */
  281.     videocursor(0,0,0);                    /* top text line */
  282.     scrstr("Rule: ");
  283.     scrstr(rule);
  284.     for (i=